home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-12 | 10.4 KB | 343 lines | [TEXT/PJMM] |
- {*}
- {** Project: uu**code engine}
- {** Author: Bernhard S. Wieser}
- {** Module: UUGlue.p}
- {** Date: 5/19/91}
- {** Revised: 6/1/91 L.R. suggested user allocate buffers}
- {** 6/8/91 L.R. suggested Pascal calling conventions}
- {** - removed table/engine globals}
- {** 6/11/91 Converted to Pascal by Leonard Rosenthol}
- {** Version: 1.0.2}
- {**}
- {** Preface:}
- {** uu**code engine is © by Bernhard S. Wieser and Octavian Micro}
- {** development, all rights reserved. Please read the accompanying}
- {** licensing agreement before use.}
- {**}
- {** Purpose:}
- {** This code should be compiled with the program using the}
- {** uu**coding engine. It loads and unloads the resource, as well as}
- {** providing 'glue' to the contained routines.}
- {** The 'glue' routines bind the various uu**coding functions}
- {** contained in the resource file to known subroutines names, thus}
- {** providing a means of easy access from a high level language.}
- {** The underlying resource routines use the Pascal calling convention.}
- {** The resources occupy <3K of memory. You must make room for}
- {** the buffers, except for the uuencode() and uudecode() routines which}
- {** require that you specify how much (contiguous) space they will allocate.}
- {** To be safe (especially with noxious INITs which invade an}
- {** applications memory), allocate at least (volume buffer size)}
- {** 524 bytes + some so as not to unexpectedly run out of memory.}
- {**}
- {** Conditions of use:}
- {** Visible credit to Bernhard S. Wieser and Octavian Micro}
- {** Development MUST be given. Written permission MUST be obtained}
- {** upon any distribution, with a licensing fee pending depending on what}
- {** it is used for.}
- {**}
- {** Algorithm:}
- {** uuencoding takes 24 bit from input stream (3 bytes) and splits}
- {** it into 32 bits (4 bytes) output. Each output byte has the top 2}
- {** bits clear, and can be translated into a printable character. The}
- {** traditional way is to simply add $20 (space). uudecoding simply}
- {** subtracts $20, strips the top 2 bits from input, and stuffs things }
- {** back together.}
- {** The encoding engine uses a translate table. Two reasons.}
- {** First, its faster than bit manipulation. Second, I can avoid}
- {** some characters (like space, which some mailers despise). This}
- {** table can be changed so long as the character, when its top 2}
- {** bits are stripped, equals its index into the table.}
- {**}
- {** Example:}
- {** '`' = $60, ' ' = $20 <- encoded}
- {** AND $3F $3F}
- {** ___ ___}
- {** $20 $20}
- {** SUB $20 $20}
- {** ___ ___}
- {** $00 $00 <- decoded}
- {**}
- {** Data Structures:}
- {** Here is the resource 'UENG' 128 jump table:}
- {** OFFSET CODE}
- {** 0 BRA encode}
- {** +4 BRA encodeOne}
- {** +8 BRA encodeLine}
- {** +C BRA uuencode}
- {** +10 BRA decode}
- {** +14 BRA decodeOne}
- {** +18 BRA decodeLine}
- {** +1C BRA uudecode}
- {**}
- {** Resource 'HEXA' 128 is an array of 64 printable characters}
- {** which equal their index when the top two bits are stripped.}
- {**}
- {** Revisions}
- {** User must now maintain the table and engine handles. User}
- {** Must also remember these are LOCKED so must be dereferenced and}
- {** passed as pointers to the core routines.}
- {*}
-
- UNIT UUIntf;
-
- INTERFACE
-
- {Main Load/Unload routines}
- FUNCTION UULoad (VAR table, engine: Handle): OSErr;
- PROCEDURE UUnload (VAR table, engine: Handle);
-
- {Core routines for UUEncoding}
- FUNCTION encodeOne (c: INTEGER; table, engine: Ptr): INTEGER;
- FUNCTION encode (three, table, engine: Ptr): OSType;
- FUNCTION encodeLine (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
- FUNCTION uuencode (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
-
- {Core routines for UUDecoding}
- FUNCTION decodeOne (c: INTEGER; engine: Ptr): INTEGER;
- FUNCTION decode (s, engine: Ptr): OSType;
- FUNCTION decodeLine (inPtr, outPtr, engine: Ptr): LONGINT;
- FUNCTION uudecode (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
-
- IMPLEMENTATION
-
- {*}
- {** UULoad}
- {** Load engine, table, move them high and lock them.}
- {**}
- {** Parameters}
- {** table handle to the encode table - passed back as a VAR}
- {** engine handle to the engine base - passed back as a VAR}
- {**}
- {** Returns}
- {** resource or memory errors}
- {*}
- FUNCTION UULoad (VAR table, engine: Handle): OSErr;
- BEGIN
- UULoad := 0;
- table := GetResource('HEXA', 128);
- IF (table <> NIL) THEN
- BEGIN
- engine := GetResource('UENG', 128);
- IF (engine <> NIL) THEN
- BEGIN
- MoveHHi(table);
- MoveHHi(engine);
- HLock(table);
- HLock(engine);
- END
- ELSE
- BEGIN
- UULoad := ResError;
- ReleaseResource(table);
- END;
- END
- ELSE
- UULoad := ResError;
- END;
-
- {*}
- {** UUnload}
- {** Get rid of the uu resources.}
- {**}
- {** Parameters}
- {** table handle to the encode table}
- {** engine handle to the engine base}
- {**}
- {** Returns}
- {** nothing}
- {*}
- PROCEDURE UUnload (VAR table, engine: Handle);
- BEGIN
- HUnlock(table);
- HUnlock(engine);
- ReleaseResource(table);
- ReleaseResource(engine);
- END;
-
- {* **}
- {** The core Pascal glue routines! **}
- {** *}
-
- {*}
- {** encodeOne}
- {** Encode one byte only, only use low 6 bits input.}
- {**}
- {** Parameters}
- {** c the character (passed as integer)}
- {** table pointer to the encode table}
- {** engine pointer to the engine base}
- {**}
- {** Returns}
- {** the encoded character (as integer)}
- {*}
- FUNCTION encodeOne (c: INTEGER; table, engine: Ptr): INTEGER;
- FUNCTION DoIt (c: INTEGER; table, engine: Ptr): INTEGER;
- INLINE
- $205F, $4EA8, $0004;
- BEGIN
- encodeOne := DoIt(c, table, engine);
- END;
-
- {*}
- {** encode}
- {** Take three bytes input, return four bytes uucoded output.}
- {**}
- {** Parameters}
- {** three pointer to an array holding at least three characters}
- {** table pointer to the encode table}
- {** engine pointer to the engine base}
- {**}
- {** Returns}
- {** four characters of encoded data in a long word}
- {*}
- FUNCTION encode (three, table, engine: Ptr): OSType;
- FUNCTION DoIt (three, table, engine: Ptr): OSType;
- INLINE
- $205F, $4E90;
- BEGIN
- encode := DoIt(three, table, engine);
- END;
-
- {*}
- {** encodeLine}
- {** Take 'insize' bytes from buffer 'in' and encode to buffer 'out'.}
- {** The size of the encode data is returned (including length and CR).}
- {** Remember, input buffer should be divisible by 3, and output size}
- {** will be 4 times the quotient (plus 2 for length and CR).}
- {**}
- {** Parameters}
- {** inPtr pointer to input buffer}
- {** insize size of input buffer}
- {** outPtr pointer to output buffer}
- {** table pointer to the encode table}
- {** engine pointer to the engine base}
- {**}
- {** Returns}
- {** length of encoded data in output buffer}
- {*}
- FUNCTION encodeLine (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
- FUNCTION DoIt (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
- INLINE
- $205F, $4EA8, $0008;
- BEGIN
- encodeLine := DoIt(inPtr, inSize, outPtr, table, engine);
- END;
-
- {*}
- {** uuencode}
- {** Encode file 'infile' to output file 'outfile', calling}
- {** 'routine' as buffers are flushed. 'routine' should be NULL}
- {** if there are no periodic tasks to perform. 'numbufrs' tells the}
- {** engine how many input/output buffers to allocate. An input}
- {** buffer is 45 bytes long, and output buffer is 62 bytes long.}
- {** Example, numbufrs = 1024 would allocate 45K+62K = 107K.}
- {**}
- {** Parameters}
- {** infile input file's file reference number}
- {** outfile output file's " " "}
- {** numbufrs number of i/o buffers to use (not size of!)}
- {** routine update procedure pointer (or NIL)}
- {** table pointer to the encode table}
- {** engine pointer to the engine base}
- {**}
- {** Returns}
- {** any error encountered}
- {*}
- FUNCTION uuencode (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
- FUNCTION DoIt (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
- INLINE
- $205F, $4EA8, $000C;
- BEGIN
- uuencode := DoIt(infile, outfile, numbufrs, routine, table, engine);
- END;
-
- {*}
- {** decodeOne}
- {** Decode one coded character.}
- {**}
- {** Parameters}
- {** c encoded character (integer passed)}
- {** engine pointer to the engine's base address}
- {**}
- {** Returns}
- {** the decoded character (integer)}
- {*}
- FUNCTION decodeOne (c: INTEGER; engine: Ptr): INTEGER;
- FUNCTION DoIt (c: INTEGER; engine: Ptr): INTEGER;
- INLINE
- $205F, $4EA8, $0014;
- BEGIN
- decodeOne := DoIt(c, engine);
- END;
-
- {*}
- {** decode}
- {** Decode 4 bytes to 3.}
- {**}
- {** Parameters}
- {** s pointer to 4 byte array of data to decode}
- {** engine pointer to the engine's base address}
- {**}
- {** Returns}
- {** the decoded data (in the upper 8 bits of a long word)}
- {*}
- FUNCTION decode (s, engine: Ptr): OSType;
- FUNCTION DoIt (s, engine: Ptr): OSType;
- INLINE
- $205F, $4EA8, $0010;
- BEGIN
- decode := DoIt(s, engine);
- END;
-
- {*}
- {** decodeLine}
- {** Decode a uucoded input in 'in' to buffer 'out'. Returns}
- {** length of decoded data.}
- {**}
- {** Parameters}
- {** inPtr pointer to an input buffer, of which first encoded}
- {** character is buffer length}
- {** outPtr pointer to the buffer to contained decoded data,}
- {** generally < 80 bytes is required.}
- {** engine pointer to the engine's base address}
- {**}
- {** Returns}
- {** the amount of decoded data (or buffer size if you like)}
- {*}
- FUNCTION decodeLine (inPtr, outPtr, engine: Ptr): LONGINT;
- FUNCTION DoIt (inPtr, outPtr, engine: Ptr): LONGINT;
- INLINE
- $205F, $4EA8, $0018;
- BEGIN
- decodeLine := DoIt(inPtr, outPtr, engine);
- END;
-
- {*}
- {** uudecode}
- {** Decode 'infile' to 'outfile', calling 'routine' on buffer flush.}
- {** 'bufsizes', unlike in uuencode, is the actual buffer size in bytes}
- {** that you want to allocated for input and output buffers.}
- {** NEVER allocate a buffer less than 10 bytes (it would be very silly).}
- {** Suggested values are multiples of 524 bytes.}
- {** Function returns error.}
- {**}
- {** Parameters}
- {** infile file reference number of input (encoded) data}
- {** outfile " " " of output (decoded) data}
- {** bufsizes the size in bytes for input and output buffers}
- {** to be allocated by uudecode()}
- {** routine the update procedure (or NIL if none)}
- {** engine pointer to the engine's base address}
- {**}
- {** Returns}
- {** any errors encountered}
- {*}
- FUNCTION uudecode (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
- FUNCTION DoIt (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
- INLINE
- $205F, $4EA8, $001C;
- BEGIN
- uudecode := DoIt(infile, outfile, bufsizes, routine, engine);
- END;
-
- END.